#!/usr/bin/perl

use strict;
use warnings;

use Getopt::Long;
use POSIX qw(strftime);

# Add current directory to INC
my $rundir;
BEGIN { use File::Basename; $rundir = dirname($0); }
use lib "$rundir";


# ------------------------------------------------------------------------------
# --- Get optional user inputted output directory. -----------------------------
# ------------------------------------------------------------------------------

my $file_lists_dir = "pdb_id_lists/";
my $verbose;

my $result = GetOptions (	"directory:s"	=> \$file_lists_dir,
							"verbose"		=> \$verbose);

if (! -d $file_lists_dir) {
	die "Aborting. No such directory: $file_lists_dir\n";
}


# ------------------------------------------------------------------------------
# --- Get current time and time of last run's query. ---------------------------
# ------------------------------------------------------------------------------

my $curr_time = strftime("%Y-%m-%d", localtime(time));

my @past_runs = glob("$file_lists_dir/pdb_id_list_*");

# If there are no prev. files, set the query min date to sometime far back.
# I don't think they had proteins back in 1900.
my $last_time = "1900-01-01";

if (scalar @past_runs > 0) {
	my @sorted_past_runs = sort { $a cmp $b } @past_runs;

	my $latest_run_file = $sorted_past_runs[-1];
	$last_time = substr $latest_run_file, -10;
}

if ($verbose) {
	print STDERR "Current time:\t$curr_time\n";
	print STDERR "Last run's time:\t$last_time\n";
}

# Abort if last run happened already today to avoid overwriting files
if ($last_time eq $curr_time) {
	die "Aborting. PDB has already been queried today.\n";
}


# ------------------------------------------------------------------------------
# --- Query PDB for multi-entity protein complexes -----------------------------
# ------------------------------------------------------------------------------

my $XML_query_start = qq(
<orgPdbCompositeQuery version="1.0">
<queryRefinement>
  <queryRefinementLevel>0</queryRefinementLevel>
  <orgPdbQuery>
    <version>head</version>
    <queryType>org.pdb.query.simple.ReviseDateQuery</queryType>
    <database_PDB_rev.date.comparator>between</database_PDB_rev.date.comparator>
);

my $XML_query_end = qq(
    <database_PDB_rev.date.max>2100-01-01</database_PDB_rev.date.max>
    <database_PDB_rev.mod_type.comparator><![CDATA[>]]></database_PDB_rev.mod_type.comparator>
    <database_PDB_rev.mod_type.value>0</database_PDB_rev.mod_type.value>
  </orgPdbQuery>
 </queryRefinement>
 <queryRefinement>
  <queryRefinementLevel>1</queryRefinementLevel>
  <orgPdbQuery>
    <version>head</version>
    <queryType>org.pdb.query.simple.SecondaryStructureQuery</queryType>
    <description>Secondary structure has:  between 1 and 1000000 Alpha Helices and between 0 and 1000000 Beta Sheets</description>
    <polyStats.helixPercent.comparator>between</polyStats.helixPercent.comparator>
    <polyStats.helixCount.comparator>between</polyStats.helixCount.comparator>
    <polyStats.sheetPercent.comparator>between</polyStats.sheetPercent.comparator>
    <polyStats.sheetCount.comparator>between</polyStats.sheetCount.comparator>
    <polyStats.helixCount.min>1</polyStats.helixCount.min>
    <polyStats.helixCount.max>1000000</polyStats.helixCount.max>
    <polyStats.sheetCount.min>0</polyStats.sheetCount.min>
    <polyStats.sheetCount.max>1000000</polyStats.sheetCount.max>
  </orgPdbQuery>
 </queryRefinement>
 <queryRefinement>
  <queryRefinementLevel>2</queryRefinementLevel>
  <conjunctionType>and</conjunctionType>
  <orgPdbQuery>
    <version>head</version>
    <queryType>org.pdb.query.simple.NumberOfEntitiesQuery</queryType>
    <description>Number of Entities Search : Entity Type=Protein Min Number of Entities=2 Max Number of Entities=1000000</description>
    <entity.type.>p</entity.type.>
    <struct_asym.numEntities.min>2</struct_asym.numEntities.min>
    <struct_asym.numEntities.max>1000000</struct_asym.numEntities.max>
  </orgPdbQuery>
 </queryRefinement>
</orgPdbCompositeQuery>
);

my $XML_query_date = "    <database_PDB_rev.date.min>" . $last_time . "</database_PDB_rev.date.min>";

my $XML_query = $XML_query_start . $XML_query_date . $XML_query_end;

if ($verbose) {
	print STDERR "XML query to PDB:\n";
	print STDERR $XML_query;
	print STDERR "\n";
}

use query_pdb qw(&search_pdb);
my @pdb_ids = search_pdb($XML_query);

if ($verbose) {
	print STDERR "\tNumber of results:\t", scalar @pdb_ids, "\n";
}


# ------------------------------------------------------------------------------
# --- Write PDB IDs to file, pdb_id_list_${time} -------------------------------
# ------------------------------------------------------------------------------

my $outfile = $file_lists_dir . '/pdb_id_list_' . $curr_time;
open (PDB_LS, ">$outfile") 
	or die "\tError: Can't open $outfile: $!";
	
foreach (@pdb_ids) {
	print PDB_LS $_ . "\n";
}

close PDB_LS;


# ------------------------------------------------------------------------------
# --- Also write PDB IDs to STDOUT ---------------------------------------------
# ------------------------------------------------------------------------------

foreach my $p (@pdb_ids) {
	print $p . "\n";
}